using System;
using System.Collections.Generic;
using System.Text;

using Outlook = Microsoft.Office.Interop.Outlook;
using System.Reflection;
using System.IO;
using Microsoft.SoftwarePlusServices.ReferenceBits.OutlookPlusServices;

namespace Microsoft.SoftwarePlusServices.ReferenceBits.OutlookPlusServices.Folders
{
    /// <summary>
    /// This class represents the prototype of a folder
    /// </summary>
    internal class IssueTrackerClass : OutlookFolder
    {
        #region Constructor
        /// <summary>
        /// 	Initializes a new instance of the object and retrieves a reference to your folder
		///     The folder is created if it doesn't exist
        /// </summary>
        /// <param name="parent">The Outlook folder that contains this folder.</param>
        public IssueTrackerClass(Outlook.Folder parent)
            : base(parent, "Issue Tracker")
        { }
        #endregion


        #region Public Methods
		//
		// TODO You need to implement these three methods in order for your folder to do anything.
		//

		///
        /// <summary>
        /// This method converts data from the web service call into an object stored in outlook.
        /// </summary>
        /// <returns>The new item created.</returns>
		///
        public Outlook.PostItem CreateItem( IssueTrackerService.Issue issue)
        {
            //patrickyong step 1, add parameter to method signature

            Outlook.UserProperty property;

            //
            // create the post item
            //
            //patrickyong step 3
			// TODO Fix these two lines to match your item type
				
           	Outlook.PostItem postItem = (Outlook.PostItem)this.Folder.Items.Add("IPM.Post.IssueTracker");
            postItem.MessageClass = "IPM.Post.IssueTracker";

			//
			// TODO Add code to add your value into the postItem's UserProperties
			//

            	// property = postItem.UserProperties.Add("YOUR-COLUMN-NAME", Microsoft.Office.Interop.Outlook.OlUserPropertyType.XXX, false, null);
            	// property.Value = YOUR-VALUE;

            //patrickyong step 3b
            //format mesage body
            string body;

            body = "<html><body>";
            body = body + "<p>" + issue.LongDescription + "</p>";

            switch (issue.CurrentStateName)
            {
                case "Pending Approval":
                    body = body + "<p><a href=\"" + "http://localhost/IssueTrackerMvcWeb/Home/ValidateIssue/" + issue.Id + "\">Issue validated</a>" + "</p>";
                    body = body + "<p><a href=\"" + "http://localhost/IssueTrackerMvcWeb/Home/RejectIssue/" + issue.Id + "\">Reject Issue</a>" + "</p>";
                    break;
                case "Pending Solution":
                    body = body + "<p><a href=\"" + "http://localhost/IssueTrackerMvcWeb/Home/SolutionCompleted/" + issue.Id + "\">Completed</a>" + "</p>"; 
                    break;
                case "Pending Testing":
                    body = body + "<p><a href=\"" + "http://localhost/IssueTrackerMvcWeb/Home/SolutionAccepted/" + issue.Id + "\">Test Accepted</a>" + "</p>";
                    body = body + "<p><a href=\"" + "http://localhost/IssueTrackerMvcWeb/Home/SolutionRejected/" + issue.Id + "\">Reject Solution</a>" + "</p>"; 
                    break;
            }

            postItem.Subject = issue.Title;
            postItem.BillingInformation = issue.CurrentStateName;

            postItem.HTMLBody = body;
            postItem.BodyFormat = Microsoft.Office.Interop.Outlook.OlBodyFormat.olFormatHTML;

            property = postItem.UserProperties.Add("Issue Title", Microsoft.Office.Interop.Outlook.OlUserPropertyType.olText, true, Outlook.OlFormatText.olFormatTextText);
            property.Value = issue.Title;

            property = postItem.UserProperties.Add("Issue Description", Microsoft.Office.Interop.Outlook.OlUserPropertyType.olText, true, Outlook.OlFormatText.olFormatTextText);
            property.Value = issue.Description;

            property = postItem.UserProperties.Add("Created Date", Microsoft.Office.Interop.Outlook.OlUserPropertyType.olDateTime, true, Outlook.OlFormatText.olFormatTextText);
            property.Value = issue.CreationDate;

            property = postItem.UserProperties.Add("Workflow State", Microsoft.Office.Interop.Outlook.OlUserPropertyType.olText, true, Outlook.OlFormatText.olFormatTextText);
            property.Value = issue.CurrentStateName;

            property = postItem.UserProperties.Add("IssueId", Outlook.OlUserPropertyType.olText, false, null);
            property.Value = issue.Id.ToString();

            postItem.UnRead = true;

			//
            // save the changes
            //
            try
            {
                postItem.Post();
            }
            catch (System.Runtime.InteropServices.COMException ex)
            {
				//
                // check if this error was caused by the item was deleted
                // this is to deal with an error that can happen if the user
                // modifies the folder structure while the async creation is 
                // happening
				//
                if (ex.ErrorCode != -2147221239)
                    throw;
            }

            return(postItem);
        }

        //patrickyong step 4
        public Outlook.PostItem UpdateItem(IssueTrackerService.Issue issue, Outlook.PostItem postItem)
        {
            Outlook.UserProperty property;

            //format mesage body
            string body;

            body = "<html><body>";
            body = body + "<p>" + issue.LongDescription + "</p>";

            switch (issue.CurrentStateName)
            {
                case "Pending Approval":
                    body = body + "<p><a href=\"" + "http://localhost/IssueTrackerMvcWeb/Home/ValidateIssue/" + issue.Id + "\">Issue validated</a>" + "</p>";
                    body = body + "<p><a href=\"" + "http://localhost/IssueTrackerMvcWeb/Home/RejectIssue/" + issue.Id + "\">Reject Issue</a>" + "</p>";
                    break;
                case "Pending Solution":
                    body = body + "<p><a href=\"" + "http://localhost/IssueTrackerMvcWeb/Home/SolutionCompleted/" + issue.Id + "\">Completed</a>" + "</p>";
                    break;
                case "Pending Testing":
                    body = body + "<p><a href=\"" + "http://localhost/IssueTrackerMvcWeb/Home/SolutionAccepted/" + issue.Id + "\">Test Accepted</a>" + "</p>";
                    body = body + "<p><a href=\"" + "http://localhost/IssueTrackerMvcWeb/Home/SolutionRejected/" + issue.Id + "\">Reject Solution</a>" + "</p>";
                    break;
            }

            postItem.Subject = issue.Title;
            postItem.BillingInformation = issue.CurrentStateName;

            postItem.HTMLBody = body;
            postItem.BodyFormat = Microsoft.Office.Interop.Outlook.OlBodyFormat.olFormatHTML;

            property = postItem.UserProperties.Add("Issue Title", Microsoft.Office.Interop.Outlook.OlUserPropertyType.olText, true, Outlook.OlFormatText.olFormatTextText);
            property.Value = issue.Title;

            property = postItem.UserProperties.Add("Issue Description", Microsoft.Office.Interop.Outlook.OlUserPropertyType.olText, true, Outlook.OlFormatText.olFormatTextText);
            property.Value = issue.Description;

            property = postItem.UserProperties.Add("Created Date", Microsoft.Office.Interop.Outlook.OlUserPropertyType.olDateTime, true, Outlook.OlFormatText.olFormatTextText);
            property.Value = issue.CreationDate;

            property = postItem.UserProperties.Add("Workflow State", Microsoft.Office.Interop.Outlook.OlUserPropertyType.olText, true, Outlook.OlFormatText.olFormatTextText);
            property.Value = issue.CurrentStateName;

            property = postItem.UserProperties.Add("IssueId", Outlook.OlUserPropertyType.olText, false, null);
            property.Value = issue.Id.ToString();

            postItem.UnRead = true;

            //
            // save the changes
            //
            try
            {
                postItem.Post();
            }
            catch (System.Runtime.InteropServices.COMException ex)
            {
                //
                // check if this error was caused by the item was deleted
                // this is to deal with an error that can happen if the user
                // modifies the folder structure while the async creation is 
                // happening
                //
                if (ex.ErrorCode != -2147221239)
                    throw;
            }

            return (postItem);
        }

        ///
        /// <summary>
        /// Any properties that are specific to your folder type should be added directly to 
        /// the Outlook folder's UserDefinedProperties collection.
        /// </summary>
        /// <param name="properties">The UserDefinedProperties object of the contained Outlook folder.</param>
        ///
        protected override void AddFolderItemProperties(Outlook.UserDefinedProperties properties)
        { 
			//
			// TODO Add code to define properties for IssueTrackerClass
			//

            // EXAMPLE: properties.Add("MY-COLUMN-NAME", Outlook.OlUserPropertyType.olText, Outlook.OlFormatText.olFormatTextText, null);
            // properties.Add("CUSTOMITEMID", Outlook.OlUserPropertyType.olText, Outlook.OlFormatText.olFormatTextText, null);

            //patrickyong, step 2
            properties.Add("IssueId", Outlook.OlUserPropertyType.olText, Outlook.OlFormatText.olFormatTextText, null);
            properties.Add("Issue Title", Microsoft.Office.Interop.Outlook.OlUserPropertyType.olText, Outlook.OlFormatText.olFormatTextText, null);
            properties.Add("Issue Description", Microsoft.Office.Interop.Outlook.OlUserPropertyType.olText, Outlook.OlFormatText.olFormatTextText, null);
            properties.Add("Created Date", Microsoft.Office.Interop.Outlook.OlUserPropertyType.olDateTime, Outlook.OlFormatDateTime.olFormatDateTimeShortDate, null);
            properties.Add("Workflow State", Microsoft.Office.Interop.Outlook.OlUserPropertyType.olText, Outlook.OlFormatText.olFormatTextText, null);

        }

        /// <summary>
        /// Implement this method to allow your scheduled tasks to
        /// not add duplicate items or to update items
        /// </summary>
        /// <param name="yourObj">an key matching an item of the type displayed in this folder</param>
        /// <returns>matching Outlook.PostItem or null if not found</returns>
        public Outlook.PostItem FindItem(string theKey)
        {
            Outlook.PostItem result = null;
			string query = "";


            //patrickyong step 5
			// TODO If you want to implement FindItem, uncomment this line and change CUSTOMITEMID to match
			// one of the fields in your item that uniquely identifies the item
            query = "[IssueId] = \"" + theKey + "\"";

            // retrieve the item by the id
            result = (Outlook.PostItem)base.Folder.Items.Find(query);

            return (result);
        }



        ///
        /// <summary>
        /// Any views that are specific to your folder type should be added directly to 
        /// the Outlook folder's Views collection.
        /// </summary>
        /// <param name="views">The Views object of the contained Outlook folder.</param>
        ///
        protected override void AddFolderViews(Outlook.Views views)
        { 
			//
			// A little bit of somewhat obscure MAPI-specific code that you must use
			// if you want to have a custom view of your items (aka custom column headers)
			
            //patrickyong step 6 change the view's name

            Outlook.TableView view = views["Issue Tracker Issues"] as Outlook.TableView;
            if (view == null)
                view = views.Add("Issue Tracker Issues", Microsoft.Office.Interop.Outlook.OlViewType.olTableView, Microsoft.Office.Interop.Outlook.OlViewSaveOption.olViewSaveOptionThisFolderEveryone) as Outlook.TableView;

            // update the settings            
            view.ShowReadingPane = true;
            
			//
			// You will most likely want to create a custom set of column headers
			// for displaying your service's data.
			//
			// In order to do this you must create a custom item view description in XML.
			// We have provided a sample which you can edit.  If you need more than one you should
			// duplicate this file and add your new file to the Resources manually
			//
			// TODO (If more than one item view) Duplicate the CustomItemView.xml file (see _Folders directory)
			// TODO (If more than one item view) Add the XML file to your Resources (open, select Files then Add... browse to XML file and click OK)
			// TODO Edit your item view XML file so it has the headers you want for your custom item view
			// TODO (If more than one item view) Change the name "CustomItemView" to match the name of the resource you just added
            view.XML = Microsoft.SoftwarePlusServices.ReferenceBits.OutlookPlusServices.Properties.Resources.CustomItemView;

			//
            // save the view settings    
            //
            view.Save();

            //
            // choose the default view
			// This code makes this new custom view the default for this folder without changing
			// the folder view for all other folders
            //
            string viewId =
                this.Folder.GetStorage("Issue Tracker Issues", Microsoft.Office.Interop.Outlook.OlStorageIdentifierType.olIdentifyBySubject).EntryID;
            Outlook.PropertyAccessor accessor = this.Folder.PropertyAccessor;
            accessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x36160102",
                accessor.StringToBinary(viewId));
        }


        #endregion
    }
}
